﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;  // FontFamily
using JHLib;


namespace JHVirtualKeyboard
{
    /// <summary>
    /// A KeyViewModel is the view-model that underlies each key-button on the keyboard.
    /// </summary>
    public class KeyViewModel : BaseViewModel
    {
        #region Constructors

        public KeyViewModel()
        {
            this.UnshiftedCodePoint = '?';
        }

        public KeyViewModel(char initialCodePoint)
        {
            this.UnshiftedCodePoint = initialCodePoint;
        }

        public KeyViewModel(KeyAssignment ka)
        {
            this.IsLetter = ka.IsLetter;
            if (String.IsNullOrEmpty(ka.FontFamilyName))
            {
                this.FontFamily = null;
            }
            else
            {
                // Those assigned to this specific key-assignment, override those assigned to the key-assignment-set.
                this.FontFamily = new FontFamily(ka.FontFamilyName);
            }
            this.UnshiftedCodePoint = (char)ka.UnshiftedCodePoint;
            this.ShiftedCodePoint = (char)ka.ShiftedCodePoint;
            this.UnshiftedToolTip = ka.UnshiftedToolTip;
            this.ShiftedToolTip = ka.ShiftedToolTip;
        }
        #endregion

        public Button Button
        {
            get { return _button; }
            set { _button = value; }
        }

        public string ButtonName
        {
            get
            {
                if (_button == null)
                {
                    return "";
                }
                else
                {
                    return _button.Name;
                }
            }
        }

        #region Text
        /// <summary>
        /// Get/set the Text to be shown on the corresponding Button
        /// </summary>
        public string Text
        {
            get
            {
                string sText;
                if (!String.IsNullOrEmpty(_text))
                {
                    sText = _text;
                }
                else
                {
                    sText = this.CodePoint.ToString();
                }
                return sText;
            }
            set
            {
                if (value != _text)
                {
                    _text = value;
                    Notify("Text");
                }
            }
        }
        #endregion

        #region IsLetter
        /// <summary>
        /// Get/set the flag that indicates whether this key-button contains a 'letter',
        /// which for our purposes means the CAPS-LOCK makes it into a capital letter.
        /// </summary>
        public bool IsLetter
        {
            get { return _isLetter; }
            set { _isLetter = value; }
        }
        #endregion

        public FontFamily FontFamily
        {
            // Note: I'm still unsure whether this would ever be merited.
            get { return _fontFamily; }
            set
            {
                if (value != _fontFamily)
                {
                    _fontFamily = value;
                    Notify("FontFamily");
                }
            }
        }

        public char UnshiftedCodePoint
        {
            get { return _unshiftedCodePoint; }
            set
            {
                if (value != _unshiftedCodePoint)
                {
                    _unshiftedCodePoint = value;
                    Notify("Text");
                }
            }
        }

        public char ShiftedCodePoint
        {
            get { return _shiftedCodePoint; }
            set
            {
                if (value != _shiftedCodePoint)
                {
                    _shiftedCodePoint = value;
                    Notify("Text");
                }
            }
        }

        public char CodePoint
        {
            get
            {
                if ((s_domain.IsShiftLock || (_isLetter && s_domain.IsCapsLock)) && _shiftedCodePoint != 0)
                {
                    return ShiftedCodePoint;
                }
                else
                {
                    return UnshiftedCodePoint;
                }
            }
        }

        public string UnshiftedToolTip
        {
            get { return _toolTip; }
            set
            {
                if (value != _toolTip)
                {
                    _toolTip = value;
                    Notify("ToolTip");
                }
            }
        }

        public string ShiftedToolTip
        {
            get { return _shiftedToolTip; }
            set { _shiftedToolTip = value; }
        }

        #region ToolTip
        /// <summary>
        /// Get the ToolTip, whether it corresponds to the unshifted or shifted codepoints.
        /// </summary>
        public string ToolTip
        {
            get
            {
                if ((s_domain.IsShiftLock || (_isLetter && s_domain.IsCapsLock)) && !String.IsNullOrEmpty(_shiftedToolTip))
                {
                    return _shiftedToolTip;
                }
                else
                {
                    return _toolTip;
                }
            }
        }
        #endregion

        public override string ToString()
        {
            var sb = new StringBuilder("KeyViewModel(");
            sb.Append(ButtonName);
            if (IsLetter)
            {
                sb.Append(",letter,");
            }
            else
            {
                sb.Append(",notletter,");
            }
            if (!String.IsNullOrEmpty(UnshiftedToolTip))
            {
                sb.Append("\"");
                sb.Append(UnshiftedToolTip);
                sb.Append("\"");
            }
            else
            {
                sb.Append("no tooltip");
            }
            sb.Append(")");
            return sb.ToString();
        }

        #region fields

        protected string _text;
        protected char _shiftedCodePoint;
        protected char _unshiftedCodePoint;
        public static KeyboardViewModel s_domain;
        protected Button _button;
        protected string _toolTip;
        protected string _shiftedToolTip;
        protected FontFamily _fontFamily;
        protected bool _isLetter;

        #endregion fields
    }
}
